Contents

References

Celeb curry cpp

Introduction

In C++ classes and structures are essentially the same thing. They both are going to create an object. The difference is conventional, they can be both used to do same task, but people choose structures to handle smaller data sets. The major difference lies in default access modifiers (public, private, protected(only be used in inheritance)). For structures the default access modifier for members or methods are public and for classes the default access modifiers is private.

Both structures and classes can have instances(objects),constructors and methods to access variables, they both pass by value. Structures are used for small data structures and classes are used to handle large data structures.

Variables, methods, and constructors are termed as members of classes or structures.

Structures

  1. Used for smaller data.
  2. Private Members can be accessed only within the body of structure definition, whereas public members are accessed by objects / or outside the definition of structures.
  3. Structures members are by default Public.

Example1 (without multiple files)

#include<iostream>

	struct person{
	std::string name;
	std::string job;
	int age;
	float salary;
	float get_bank_info()
	{
		return Bank_balance;
	}
	private:
		float Bank_balance=15000;
	};

	int main()
	{
	person me;
	me.age=28;
	me.name="vishal rao";
	me.job="Phd Student";
	me.salary=37000;
	std::cout<<"my age is "<<me.age<<std::endl;
	std::cout<<"bank balance is :"<<me.Bank_balance<<std::endl; //will generate error as we can't access private members of object me, which is instance of structure 'person'
	std::cout<<"bank info is :"<<me.get_bank_info();

	return 0;
	}


Classes

Example


#include<iostream>

	class person{
	float Bank_balance=15000;
	public:
		std::string name;
		std::string job;
		int age;
		float salary;
		float get_bank_info()
		{
			return Bank_balance;
		}
	};

	int main()
	{
	person me;
	me.age=28;
	me.name="vishal rao";
	me.job="Phd Student";
	me.salary=37000;
	std::cout<<"my age is "<<me.age<<std::endl;
	/* std::cout<<"bank balance is :"<<me.Bank_balance<<std::end; //will generate error as we can't access private members of object me, which is instance of structure 'person' */
	std::cout<<"bank info is :"<<me.get_bank_info()<<std::endl;

	return 0;
	}

Constructor and Destructor

Constructors

Default Constructor
Custom Constructor
Remarks (this-> pointer)

Destructor

Working with Objects

Encapsulation

There are two ways to achieve Encapsulation: 1. Access Modifiers and 2. Getters and setters

Getters And Setters

Example:
In Below program the function get_bank_balance(getter) and set_bank_balance(is setter)

#include<iostream>
using std::cout;
using std::endl;
using std::string;

	class person{
	float Bank_balance=15000;
	public:
		string name;
		string job;
		int age;
		float salary;
		float get_bank_balance()
		{
			return Bank_balance;
		}
		void set_bank_balance(float balance)
		{
		if (balance>=200000){
			cout<<"have you forgot to pay the mess+hostel+fee"<<endl;
			Bank_balance=balance;}
		else:
			Bank_balance=balance;
		}
		person(string name_user, string job_name,int age_user, float salary_user ){
		cout<<"a custom constructor is called since an object is created using custom constructor\n";
		this->name=name_user;           // or we can just use name=name_user
		this->job=job_name;       // or job=job_name;
		this->age=age_user;       // or age=age_user;
		this->salary=salary_user;
		}
		
		person(){cout<<"a default constructor is called since an object is created with default constructor\n";}
		~person(){cout<<"object is destroyed using this destructor \n";} //unnecessary as it is automatically / implicitly created by compiler.

	};
	int main()
	{
	//person me; will not work as implicit constructor is only there if we don't define any constructor.
	person vishal("vishal rao","jrf",28,37000); 
	vishal.set_bank_balance(300000);
	cout<<"new bank balance is "<<vishal.get_bank_balance()<<endl;
	return 0;
}

Static Data Members

These data members are specific to class and no instance(object) of class can use them. We can define Static variables, and Static Methods for any class. Example:

#include<iostream>
using std::cout;
using std::endl;
using std::string;

	class person{
	float bank_balance=15000;
	static int user_count;
	public:
		string name;
		string job;
		int age;
		float salary;
		static void get_user_count()
		{
			cout<<"total number of users are:"<<user_count<<endl; //each time an object is created we shall increase the count and each time an object is destroyed we decrease the count.
	//		cout<<age; //will throw some error as we can't use non static member inside static member method
		}
		float get_bank_balance()
		{
			return bank_balance;
		}
		
		person(string name, string job_name,int age_user, float salary_user ){
		cout<<"a custom constructor is called since an object is created using custom constructor\n";
		this->name=name;           // since both names are same, we need this-> pointer
		job=job_name;       // or job=job_name;
		age=age_user;       // or age=age_user;
		salary=salary_user;
		user_count++;
		}
		
		person(){
		user_count++;
		cout<<"a default constructor is called since an object is created with default constructor\n";}
		~person(){
		user_count--;
		cout<<"object is destroyed using this destructor \n";} //unnecessary as it is automatically / implicitly created by compiler.

	};
	
// we need to initialise the user_count and we can only do that outside the definition of class. (since there can be more users before we implement this program)
int person::user_count=0; 

	int main()
	{
	person user1,user2,user3,user4;
	user1.get_user_count(); 
	person::get_user_count();              //get_user_count is static member, it can't be called from users. 
	user1.~person(); //user1 gets destroyed. 
	person::get_user_count();
	return 0;
}


Operator Overloading

Example1 addition operator (defining inside class)

#include<iostream>
using std::endl;
using std::cout;

class position{
	public:
		int x;
		int y;
		position operator+ (position pos){
		position new_position;
		new_position.x=x+pos.x;
		new_position.y=y+pos.y;
		return new_position;
		}
	
};

int main()
{

position a,b;
a.x=10;
a.y=15;
b.x=3;
b.y=5;

//we cant define position c=a+b; as operator + is not defined for such objects of type position(user defined data type)
//we need to define the operator overloading in public access modifier.
position c;
c=a+b;
cout<<"The x coordinates of c is "<<c.x<<" "<<c.y<<endl;
return 0;
}

Example2 Comparison Operator{==} (defining outside the class)

we first need to declare the operator overloading method inside the class, then only we can define it outside the class.

#include<iostream>
using std::endl;
using std::cout;

class position{
	public:
		int x;
		int y;
		position operator+ (position pos){
		position new_position;
		new_position.x=x+pos.x;
		new_position.y=y+pos.y;
		return new_position;
		}
		bool operator==(position pos);
};

//let us do the operator overloading definition outside the class, since it has been declared inside once. 
bool position::operator ==(position pos){
	if(pos.x==position::x && pos.y==position::y){
		return true;
	}
	else{
	return false;
	}
}
int main()
{
	position a,b;
	a.x=10;
	a.y=15;
	b.x=3;
	b.y=5;

	//we cant define position c=a+b; as operator + is not defined for such objects of type position(user defined data type)
	//we need to define the operator overloading in public access modifier.
	position c;
	c=a+b;
	cout<<"The x coordinates of c is "<<c.x<<" "<<c.y<<endl;
	if (a==b){
		cout<<"a and b are equal"<<endl;
	}
	else{
		cout<<"a and b are different"<<endl;
	}
return 0;
}

Example 3 Insertion(>>) and Extraction(<<) operator


#include<iostream>
using std::endl;
using std::cout;
using std::cin;

class position{
	public:
		int x;
		int y;
		};

//let us do the operator overloading definition outside the class, since it has been declared inside once. 
std::istream& operator >> (std::istream &input, position &pos){
cout<<"enter x coordinates of this position"<<endl;
input>>pos.x;
cout<<"enter y coordinates of this position"<<endl;
input>>pos.y; 
cout<<"Thanks, position has been entered"<<endl;
return input;
}
std::ostream& operator << (std::ostream &output, position &pos){
output<<"x coordinates:"<<pos.x<<" Y coordinates:"<<pos.y;
return output;
}

int main()
{
	position a,b;
	// we would like to take entries from user and print the positions a and b.
	//cin>>a,b; won't work as cin is object of type std::istream and a is object of type position.we need to define what does >> mean if we like to use this functionality.
	cin>>a; 
	cin>>b;
	cout<<a<<endl;
	cout<<b<<endl;
return 0;
}

Friend functions to access private Members

We can define Friend functions in private member list of class and within definition of friend functions we can use private members.
Note: we can not give any parameters to friend function, we have to provide object of type class as parameter to friend function.

Example (without overloading)

#include <iostream>
#include <cmath>
using std::cout;
using std::endl;

class position{
	public:
		float x=0;
		float y=0;
		friend float get_position(position pos);
	private:
		float radius(float xcord, float ycord){
		return std::pow((xcord*xcord+ycord*ycord),0.5);
		}
};
float get_position(position pos){
	return pos.radius(pos.x,pos.y); // accessing private member radius() to calculate the radius.
}
int main(){
	position a;
	a.x=3;
	a.y=4;
	cout<<"the distance to origin is  "<<get_position(a)<<endl;
	return 0;
 }

Example (with overloading)


#include<iostream>
using std::endl;
using std::cout;
using std::cin;

class position{
	public:
		int x;
		int y;
		friend std::ostream& operator << (std::ostream &output, position &pos);
	private:
		std::string status="Real";
		};

//let us do the operator overloading definition outside the class, since it has been declared inside once. 
std::istream& operator >> (std::istream &input, position &pos){
cout<<"enter x coordinates of this position"<<endl;
input>>pos.x;
cout<<"enter y coordinates of this position"<<endl;
input>>pos.y; 
cout<<"Thanks, position has been entered"<<endl;
return input;
}
std::ostream& operator << (std::ostream &output, position &pos){
output<<"x coordinates:"<<pos.x<<" Y coordinates:"<<pos.y<<endl;
output<<"these are "<<pos.status<<endl; //using private member as it is a friend function declared in public access of class.
return output;
}

int main()
{
	position a,b;
	// we would like to take entries from user and print the positions a and b.
	//cin>>a,b; won't work as cin is object of type std::istream and a is object of type position.we need to define what does >> mean if we like to use this functionality.
	cin>>a; 
	cin>>b;
	cout<<a<<endl;
	cout<<b<<endl;
return 0;
}

Classes Across Multiple Program files

What if we have to write a huge program with so many classes, namespaces and functions, it is always better to write the function definitions, in one file(named as program.cpp) and all variables, data structure(class and structures), and functions declaration in separate file(program.h).

Steps:

  1. Move all function, members,data structures in header file and name it "headerfile.h". {we have to make sure that we don't define these variables/members twice, to do that we use `#ifndef HEADERFILE_H #define HEADERFILE_H //all function definitions #endif `
  2. Define all functions (method of class/ methods of structures and any functions) in separate file "program.cpp", inside this file , include header file "headerfile.h".
  3. Now write a separate program for int main() and include the header file using #include "headerfile.h"

Now I am going to do it for above functions and class methods and class members

Defining header file: classes.h

#ifndef CLASSES_H
#define CLASSES_H

#include<iostream>
#include <ostream>
using std::string;

class person{
	float Bank_balance=15000;
 	public:
		std::string name;
		std::string job;
		int age;
		float salary;
		float get_bank_info();
		person(std::string name, string job_name,int age_user, float salary_user );
		person();
		~person();
};
class position{
	public:
		int x;
		int y;
		position operator+ (position pos);
		bool operator==(position pos);
	
};
std::istream& operator>>(std::istream& input, position pos);
std::ostream& operator<<(std::ostream& output, position pos);
#endif

Defining all functions

definition_program.cpp

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include "headerfiles/classes.h"

/* float person::Bank_balance=15000; */
float person::get_bank_info()
		{
			return Bank_balance;
		}
person::person(string name, string job_name,int age_user, float salary_user ){
		cout<<"a custom constructor is called since an object is created using custom constructor\n";
		this->name=name;
		this->job=job_name;
		this->age=age_user;
		this->salary=salary_user;
		}
person::person(){cout<<"a default constructor is called since an object is created \n";} //defining default constructor as it won't be created by compiler if we have defined our custom constructor with parameters above.
person::~person(){cout<<"object is destroyed \n";} //unnecessary as it is automatically / implicitly created by compiler.
												   //
position position::operator+ (position pos){
position new_position;
new_position.x=x+pos.x;
new_position.y=y+pos.y;
return new_position;
}

bool position::operator ==(position pos){
	if(pos.x==position::x && pos.y==position::y){
		return true;
	}
	else{
	return false;
	}
}

std::istream& operator >> (std::istream &input, position &pos){
cout<<"enter x coordinates of this position"<<endl;
input>>pos.x;
cout<<"enter y coordinates of this position"<<endl;
input>>pos.y; 
cout<<"Thanks, position has been entered"<<endl;
return input;
}

std::ostream& operator<<(std::ostream& output, position pos){
output<<"x coordinates:"<<pos.x<<" Y coordinates:"<<pos.y<<endl;
return output;
}

Using headerfile.h and the definition_file.cpp

Now compile the program with g++ thisprogramname.cpp definition_program.cpp

#include <iostream>
#include "headerfiles/classes.h"
using std::cout;
using std::endl;

int main()

{
	person p1, p2;
	p1.name="vishal";
	p2.name="naresh";
	position a,b;
	a.x=2;
	a.y=4;
	b.x=2;
	b.y=4;
	cout<<a<<" "<<b<<endl;
	if (a==b){
		cout<<"both positions are same"<<endl;
	}
	else{
		cout<<"both positions are different"<<endl;
	}

	
	return 0;
}

`output:
a default constructor is called since an object is created
a default constructor is called since an object is created
x coordinates:2 Y coordinates:4
x coordinates:2 Y coordinates:4

both positions are same
object is destroyed
object is destroyed
`

Inheritance

Assume that we have created a class for school_members. Now school_members can be teacher and students. We now want to create separate classes for student and teacher and inherit the methods and members of parent class (school_members), we can do so by just using :

class teacher: Public school_members{}
class student: Public school_members{}

Even though we have not defined these classes, we can still create the objects and use the already available public members of Parent class.
`teacher t1,t2;
student s1,s2;
s1.name="vishal";
s2.name="naresh";
t1.age=45;
t2.age=50;
`

Example1 (without header files)



#include<iostream>
using std::cout;
using std::endl;
using std::string;
class person{
	float bank_balance=15000;
	static int user_count;
	public:
		string name;
		string job;
		int age;
		float salary;
		static void get_user_count()
		{
			cout<<"total number of users are:"<<user_count<<endl; //each time an object is created we shall increase the count and each time an object is destroyed we decrease the count.
	//		cout<<age; //will throw some error as we can't use non static member inside static member method
		}
		float get_bank_balance()
		{
			return bank_balance;
		}
		
		person(string name, string job_name,int age_user, float salary_user ){
		cout<<"a custom constructor is called since an object is created using custom constructor\n";
		this->name=name;           // since both names are same, we need this-> pointer
		job=job_name;       // or job=job_name;
		age=age_user;       // or age=age_user;
		salary=salary_user;
		user_count++;
		}
		
		person(){
		user_count++;
		cout<<"a default constructor is called since an object is created with default constructor\n";}
		~person(){
		user_count--;
		cout<<"object is destroyed using this destructor \n";} //unnecessary as it is automatically / implicitly created by compiler.

	};
	
int person::user_count = 0;

// here we can define new child classes called as teacher and student

class teacher : public person{
	public:
		teacher(string name, string job_name,int age_user, float salary_user ){
			this->name=name;           // since both names are same, we need this-> pointer
			job=job_name;       // or job=job_name;
			age=age_user;       // or age=age_user;
			salary=salary_user;

		}
};
class student : public person{
	public:
		student(string name, string job_name,int age_user, float salary_user ){
			this->name=name;           // since both names are same, we need this-> pointer
			job=job_name;       // or job=job_name;
			age=age_user;       // or age=age_user;
			salary=salary_user;

		}
};
int main()
{
teacher t1("teacher1","teacher",44,230000);
person::get_user_count();
student s1("student1","student",16,0000);
person::get_user_count();
cout<<"name of teacher1 is "<<t1.name<<endl;
cout<<"name of student is "<<s1.name<<endl;

return 0;
}


`output:

a default constructor is called since an object is created with default constructor
total number of users are:1
a default constructor is called since an object is created with default constructor
total number of users are:2
name of teacher1 is teacher1
name of student is student1
object is destroyed using this destructor
object is destroyed using this destructor
`

Example2 (with header files)

  1. first we will create the main function
    
    
    /* #include <iostream> //defined in classes.h so no need */
    /* #include <string.h>  //defined in classes.h so no need*/
    #include "classes.h"
    /* using std::cout; //defined in classes.h so no need*/
    
    int main(int argc, char *argv[])
    {
    	teacher t1;	
    	t1.age=25;
    	t1.name="prof. A J";
    	cout<<t1.name<<" "<<t1.age<<endl;
    	return 0;
    }
    
    
  2. Then we shall add the declaration in header file , here in "classes.h"
    
    #ifndef CLASSES_H
    #define CLASSES_H
    
    #include<iostream>
    #include <ostream>
    using std::string;
    using std::endl;
    using std::cout;
    class person{
    	float Bank_balance=15000;
     	public:
    		std::string name;
    		std::string job;
    		int age;
    		float salary;
    		float get_bank_info();
    		person(std::string name, string job_name,int age_user, float salary_user );
    		person();
    		~person();
    };
    class position{
    	public:
    		int x;
    		int y;
    		position operator+ (position pos);
    		bool operator==(position pos);
    	
    };
    
    class teacher: public person{
    	public:
    		teacher();
    };
    class student: public person{
    	public:
    		student();
    };
    
    std::istream& operator>>(std::istream& input, position pos);
    std::ostream& operator<<(std::ostream& output, position pos);
    #endif
    
    
  3. Then we shall define these functions in classes_across_files.cpp
    
    
    
    #include <iostream>
    using std::cout;
    using std::endl;
    #include "classes.h"
    
    /* float person::Bank_balance=15000; */
    float person::get_bank_info()
    		{
    			return Bank_balance;
    		}
    person::person(string name, string job_name,int age_user, float salary_user ){
    		cout<<"a custom constructor is called since an object is created using custom constructor\n";
    		this->name=name;
    		this->job=job_name;
    		this->age=age_user;
    		this->salary=salary_user;
    		}
    person::person(){cout<<"a default constructor is called since an object is created \n";} //defining default constructor as it won't be created by compiler if we have defined our custom constructor with parameters above.
    person::~person(){cout<<"object is destroyed \n";} //unnecessary as it is automatically / implicitly created by compiler.
    
    
    teacher::teacher(){
    	cout<<"teacher object is created with default constructor"<<endl;
    }
    
    student::student(){
    	cout<<"student object is created with default constructor"<<endl;
    }
    
    
    //
    position position::operator+ (position pos){
    position new_position;
    new_position.x=x+pos.x;
    new_position.y=y+pos.y;
    return new_position;
    }
    
    bool position::operator ==(position pos){
    	if(pos.x==position::x && pos.y==position::y){
    		return true;
    	}
    	else{
    	return false;
    	}
    }
    
    std::istream& operator >> (std::istream &input, position &pos){
    cout<<"enter x coordinates of this position"<<endl;
    input>>pos.x;
    cout<<"enter y coordinates of this position"<<endl;
    input>>pos.y; 
    cout<<"Thanks, position has been entered"<<endl;
    return input;
    }
    
    std::ostream& operator<<(std::ostream& output, position pos){
    output<<"x coordinates:"<<pos.x<<" Y coordinates:"<<pos.y<<endl;
    return output;
    }
    
    
    
  4. Then we shall compile the main.cpp program g++ inheritance_with_header_files.cpp classes_across_files.cpp

`output:

a default constructor is called since an object is created
teacher object is created with default constructor
prof. A J 25
object is destroyed
`

Polymorphism

If we define same functions again in child class then which function will be called? , to resolve the conflict we use virtual keyword before the function which we want to ignore. Functions can be overloaded in case we have different types of arguments, or no arguments at all, but there can be two similar functions with same type of parameters. In that case we need the virtual keyword before the name of function which we would like to ignore.

It is of two type:

  1. Compile type
    1. function overloading (simply define same name functions with different data types, return types, or no parameters, better to use generic programming or use of templates.)
    2. operator overloading
  2. Run type
    1. virtual functions

We have looked at function overloading and operator overloading. Now we shall look at virtual functions.

Example (virtual functions):


#include<iostream>
using std::cout;
using std::cin;
using std::endl;

class base{
	public:
		virtual	void fun(){
		cout<<"this is function of base class with no parameters"<<endl;
		}
		virtual	void fun(int a){
		cout<< "this is function of base class with some argument "<<endl;
		}

		virtual	void fun(double b){
		cout<<"this is function of base class for double parameters "<<endl;
		}
		
};

class child: public base{
public:
	void fun(){
	cout<<"this is function of child class and has no arguments"<<endl;
	}
	void fun(int a){
		cout<< "this is function in child class with some int argument "<<endl;
	}

	void fun(double b){
		cout<<"this is function called in child class for double parameters "<<endl;
	}
};

int main(){

child c1;
//now since c1 is object of child class , it inherits all public methods of base class, so if I call c1.fun() then which function will be called? It will call function of child class.
c1.fun(); 
//what if I define a pointer of base class and store address of child object in it?
base *basePtr;
basePtr = &c1;
basePtr->fun(); //which function will be called now? it will call function of base class, but since we have given the address of child object, it must call function for child class objects.To do that we will put `virtual` keyword in front of function definition of base classes.
c1.fun(4);
c1.fun(4.3);
return 0;
}

`output:

this is function of child class and has no arguments
this is function of child class and has no arguments
this is function in child class with some int argument
this is function called in child class for float parameters

`